use clap::Parser;
use clap::ValueEnum;
use std::fs;
use std::path::Path;
use std::io::Write;

#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, ValueEnum)]
enum Algorithm {
    XOR,
}
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, ValueEnum)]
enum Method {
    ENCRYPT,
    DECRYPT,
}

#[derive(Parser)]
#[command(name = "FileEncrypt")]
#[command(author = "Creator")]
#[command(version = "1.0")]
#[command(about = "对指定文件按照指定方式进行加密并生成新文件", long_about = None)]
struct Cli {
    // 注意下面的注释是三个斜杠!!!
    /// 操作， 加密还是解密
    #[arg(value_enum, short, long)]
    method: Method,
    /// 加密算法
    #[arg(value_enum, short, long, default_value="XOR")]
    algorithm: Algorithm,

    /// 输入文件名
    #[arg(long, short = 'i')]
    filename_input: Option<String>,

    /// 输出文件名
    #[arg(long, short = 'o')]
    filename_output: Option<String>,

    /// 加密密钥
    #[arg(long, short = 'k')]
    key : u8,
}

fn xor(raw_data : &mut [u8], key : u8) {
    for byte in raw_data{
        *byte = *byte ^ key;
    }
}

fn main() {
    let cli = Cli::parse();
    let method = cli.method;
    let algorithm = cli.algorithm;
    let input_file = match cli.filename_input {
        Some(input_file) => input_file,
        None => {
            println!("小子!必须输入一个文件.");
            return;
        }
    };
    let key = cli.key;
    let inputfile_path = Path::new(input_file.as_str());
    if inputfile_path.exists() {
        let file_bytes = fs::read(inputfile_path).expect("小子!文件打不开，是不是搞错了？");
        let mut bytes_output: Vec<u8> = file_bytes.clone();

        match algorithm {
            Algorithm::XOR => {
                xor(&mut bytes_output, key);
            },
            _ => {
                println!("嘛玩意儿？这个是算法嘛？");
            }
        }
        let output_filename = match cli.filename_output {
            Some(filename_output) => filename_output,
            None => {
                match method {
                    Method::ENCRYPT => input_file + ".pe",
                    Method::DECRYPT => input_file.replace(".pe", "")
                }
            }
        };
        let outputfile_path = Path::new(&output_filename);
        if let Ok(mut outputfile) = fs::File::create(outputfile_path) {
            outputfile.write(bytes_output.as_slice()).unwrap();
        }
        println!("任务完成！");

    } else {
        println!("小子! 文件不存在, 你敢耍我!");
    }
}
